var arguments = process.argv.splice(2);
var param1 = arguments[0];
// console.log('param1:', param1)

//将字符串转化为json
const str2json = function(srcStr) {
	let json = JSON.parse(srcStr); // (new Function("return " + srcStr))(); // eval('(' + srcStr + ')'); // 
	return json;
}

//-----------------------------------------------------------------------------------------------------

//获取json长度
const getJsonLength = function (jsonData) {
    //return Object.keys(jsonData).length;
    var jsonLength = 0;
    Object.keys(jsonData).forEach(item => { // for (var item in jsonData) {
        jsonLength++;
    })
    return jsonLength;
}

//获取类型
const getType = function (data) {
    if ("MC" == data.QuestionType) {//选择类
        if ("SAVR" == data.Selector) {
            return "单选";
        } else if ("DL" == data.Selector) {
            return "下拉选项";
        } else if ("SB" == data.Selector) {
            return "单选";//"单选盒";
        } else if ("MAVR" == data.Selector) {
            return "多选";
        } else if ("NPS" == data.Selector) {
            return "量表";//nps量表
        } else if ("SAHR" == data.Selector) {
            return "单选";//补充未遇到的单选类型
        } else if ("MACOL" == data.Selector){
            return "多选";//目前看到的现象是：两列超级多选项的多选题
        } else {
            return "未知选题";
        }
    } else if ("TE" == data.QuestionType) {//输入框类
        if ("SL" == data.Selector) {
            return "填空";//单行填空
        } else if ("ML" == data.Selector) {
            return "文本框";
        } else if ("ESTB" == data.Selector) {
            return "文本框";//"文章";
        } else if ("PW" == data.Selector) {
            return "填空";//"密码";
        } else if ("FORM" == data.Selector) {
            return "填空";//"表单式填空";也可以视为多项填空
        } else {
            return "未知输入框";
        }
        // } else if ("upload" == data.QuestionType) {
        //     return "文件上传";
    } else if ("Slider" == data.QuestionType) {//滑动条类和五角星量表（可为单行或矩阵式）
        let choicesNum = Object.keys(data.Choices).length;
        if ("HSLIDER" == data.Selector) {//带拨环条形
            if(choicesNum > 1) {
                return "矩阵滑动";
            } else {
                return "滑动条";
            }
        } else if ("HBAR" == data.Selector) {//无拨环条形
            if(choicesNum > 1) {
                return "矩阵滑动";
            } else {
                return "滑动条";
            }
        } else if ("STAR" == data.Selector) {//"五角星量表"(属于打分题);//五角星后还有选取的值，可通过输入选取
            return "矩阵量表";//注：即使只有一行也视为矩阵量表，以方便提交统一处理
        } else {
            return "未知滑条";
        }
        // return "量表";//NPS
    } else if ("RO" == data.QuestionType) {//rank order（拖动排序）
        return "排序选择";
    } else if ("Matrix" == data.QuestionType) {//矩阵类
        if ("Likert" == data.Selector) {//文字在左和上，有效区为选择区
            if ("SingleAnswer" == data.SubSelector) {//矩阵单选
                return "矩阵单选";
            } else if ("MultipleAnswer" == data.SubSelector) {//矩阵多选
                return "矩阵多选";
            } else if ("DL" == data.SubSelector) {//矩阵下拉
                return "矩阵单选";
            } else {// if ("DND" == data.SubSelector) {//矩阵拖放
                return "矩阵单选";
            }
        } else if ("Bipolar" == data.Selector) {//文字在左和右，有效区为单选
            return "矩阵单选";
        } else if ("RO" == data.Selector) {//Rank order的简写，文字在左和上，有效区为输入框
            return "矩阵填空";
        } else if ("CS" == data.Selector) {//常量计算总和，文字在左和上，有效区为输入框(可输入负数)，最右边有自动计算该行总和的Total列
            return "矩阵计算总和";//暂时不支持
        } else if ("TE" == data.Selector) {//Text entry的简写，文字在左和上，有效区为输入框
            return "矩阵填空";
        } else if ("MaxDiff" == data.Selector) {//文字在中间和上边，有效区为两列单选且分布于文字两边
            return "矩阵单选";
        } else {
            return "未知矩阵";
        }
    } else if ("SBS" == data.QuestionType) {//并排：文字在左和上的多组双列矩阵
        return "矩阵单选";//"并排矩阵";
    } else if ("DB" == data.QuestionType) {
        return "占位题";//显示文本，图像，或文件
    } else if("Timing" == data.QuestionType) {
        return "占位题";//页面计时器
    } else if("Meta" == data.QuestionType) {
        return "占位题";//元数据，比如Selector值为Browser表明为浏览器相关信息
    } else {
        return "未知";
    }
}

//通用匹配提取
const getMatchedStrs = function (str, reg) {
    return str.match(reg)[1];
}

//获取选项填空id
const getBlankId = function (text) {
    return getMatchedStrs(text, /data-id=&quot;(\S*?)&quot;/);
}

//获取选项
const getOptions = function (qst, curObj) {
    let type = curObj.type;
    let inner = new Array();
    let la = qst.SurveyLanguage;
    let la_zh = "";
    if (qst.Language.hasOwnProperty("ZH-S")) {//简体中文
        la_zh = "ZH-S";
    } else if(qst.Language.hasOwnProperty("ZH-T")) {//繁体中文
        la_zh = "ZH-T";
    }
    let choises = getChoices(qst, la, la_zh);
    let answers = getAnswers(qst, la, la_zh);
    let topChoices = qst.Choices;//顶层选项，不依赖于语言

    if(null == choises || undefined == choises) {//处理“Object.keys不能处理无key的项”的情况
        return inner;
    }

    //打分题(也视为矩阵量表)处理
    if(-1 != type.indexOf('矩阵量表') && 'Slider|STAR' == curObj.srcType) {
        let choicesNum = Object.keys(topChoices).length;
        let starCount = qst.Configuration.StarCount;
        Object.keys(choises).forEach(ckey => { // for (let ckey in choises) {
            let counter = 0;
            for (let i = 1; i <= starCount; i++) {
                let tmpObj = new Object();
                const val = ++counter; 
                tmpObj.title = choises[ckey].Display + "_" + val;
                tmpObj.optionId = ckey + "_" + i + "_" + val;
                tmpObj.value = val;
                inner.push(tmpObj);
            }
        })
        return inner;
    }

    //矩阵滑动处理
    if(-1 != type.indexOf("矩阵滑动")) {
        Object.keys(choises).forEach(ckey => { // for (let ckey in choises) {
            let counter = 0;
            // Object.keys(answers).forEach(akey => { // for (let akey in answers) {
            let tmpObj = new Object();
            const val = ++counter; 
            let minVal = qst.Configuration.CSSliderMin;
            let maxVal = qst.Configuration.CSSliderMax;
            tmpObj.title = choises[ckey].Display + "_" + minVal + "_" + maxVal;
            tmpObj.optionId = ckey.toString();
            tmpObj.value = val;
            inner.push(tmpObj);
            // })
        })
        return inner;
    }

    //通用矩阵类处理
    if(-1 != type.indexOf("矩阵")) {
        if(null == answers || undefined == answers) {//处理“Object.keys不能处理无key的项”的情况
            // answers为空则换查AdditionalQuestions，目前仅发现在矩阵打分题中出现过
            if(!qst.hasOwnProperty("AdditionalQuestions")) {
                return inner;
            }
            let aqsts = qst.AdditionalQuestions;
            if(null == aqsts || undefined == aqsts) {//处理“Object.keys不能处理无key的项”的情况
                return inner;
            }
            Object.keys(aqsts).forEach(aqkey => { // for (let aqkey in aqsts) {
                choises = aqsts[aqkey].Language[la].Choices;
                answers = aqsts[aqkey].Language[la].Answers;
                if(null == choises || undefined == choises) {
                    return inner;
                }
                if(null == answers || undefined == answers) {
                    return inner;
                }
                Object.keys(choises).forEach(ckey => { // for (let ckey in choises) {
                    let counter = 0;
                    Object.keys(answers).forEach(akey => { // for (let akey in answers) {
                        let tmpObj = new Object();
                        const val = ++counter; 
                        tmpObj.title = choises[ckey].Display + "_" + akey + "_" + answers[akey].Display;//格式：行名_列id_列名
                        tmpObj.optionId = ckey + "_" + akey + "_" + val;//格式：行ID_列ID_序号
                        tmpObj.value = val;
                        inner.push(tmpObj);
                    })
                    if (topChoices[ckey].hasOwnProperty("TextEntry") && "true" == topChoices[ckey].TextEntry) {
                        curObj.type += "带填空";
                    }
                })
                return inner;
            });
        }

        Object.keys(choises).forEach(ckey => { // for (let ckey in choises) {
            let counter = 0;
            Object.keys(answers).forEach(akey => { // for (let akey in answers) {
                let tmpObj = new Object();
                const val = ++counter; 
                tmpObj.title = choises[ckey].Display + "_" + akey + "_" + answers[akey].Display;//格式：行名_列id_列名
                tmpObj.optionId = ckey + "_" + akey + "_" + val;//格式：行ID_列ID_序号
                tmpObj.value = val;
                inner.push(tmpObj);
            })
            if (topChoices[ckey].hasOwnProperty("TextEntry") && "true" == topChoices[ckey].TextEntry) {
                curObj.type += "带填空";
            }
        })
        return inner;
    }

    //通用处理
    Object.keys(choises).forEach(key => { // for (let key in choises) {
        let tmpObj = new Object();
        tmpObj.title = choises[key].Display;
        if (topChoices[key].hasOwnProperty("TextEntry") && "true" == topChoices[key].TextEntry) {
            if(-1 != type.indexOf("单选") || -1 != type.indexOf("多选")) {
                tmpObj.title += "|underline";
            }
        }   
        tmpObj.optionId = key.toString();
        tmpObj.value = -1;
        inner.push(tmpObj);
    })
    return inner;
}

//获取是否必须
const getRequired = function (qst) {
    if("None" == qst.Validation){//timing类型特殊处理
        return false;
    }
    //处理Validation不存在的情况
    if(null == qst.Validation || undefined == qst.Validation) {
        return false;
    }
    let qps = qst.Validation.Settings;
    if (qps.hasOwnProperty("ForceResponse")) {
        if ("OFF" == qps.ForceResponse) {
            return false;
        } else {//包含ON和RequestResponse两种值
            return true;
        }
    }
    return false;
}

//清洗文本
const cleanText = function (text) {
    let tmp = text.replace(/<[^<>]*>/g, "");
    tmp = tmp.trim();//仅去除首尾空格 // tmp = tmp.replace(/\s/gim, "");//去除所有空白
    return tmp;
}

//获取标题
const getTitle = function (qst) {
    let la = qst.SurveyLanguage;
    if (qst.Language.hasOwnProperty("ZH-S")) {//简体中文
        la = "ZH-S";
    } else if(qst.Language.hasOwnProperty("ZH-T")) {//繁体中文
        la = "ZH-T";
    }
    if(undefined == qst.Language[la].QuestionText || null == qst.Language[la].QuestionText) {//存在没有标题的情况
        return "";
    }
    let title = cleanText(qst.Language[la].QuestionText);
    return title.replace("_", "");
}

//获取选项号
const getChoiceNo = function (str) {
    let idx = str.lastIndexOf("/");
    return str.substring(idx + 1);
}

//获取显示逻辑关系
const getRelation = function (displayLogic) {
    if (isEmpty(displayLogic)) {
        return "";
    }
    let topicDict = { 'And': '|', 'Or': '$' };//根据框架依照问卷星规则：逻辑与用|，逻辑或用$
    let optionDict = { 'And': '.', 'Or': ';' };
    let operDict = { 'Selected': '', 'NotSelected': '-', 'Displayed': '', 'NotDisplayed': '-' }
    //forEach无法使用 break，continue 跳出循环，使用 return 时，效果和在 for 循环中使用 continue 一致；无法遍历对象，仅适用于数组的遍历。
    let result = "";
    let unmanageable = "";//无法处理的
    Object.keys(displayLogic).forEach(key => { // for (let key in displayLogic) {
        if (-1 == key.indexOf("0")) {
            return;//continue;
        }
        let retDict = [];
        let tmpObj = displayLogic[key];
        Object.keys(tmpObj).forEach(tk => { // for (let tk in tmpObj) {
            if (-1 != tk.indexOf("Type")) {
                return;//continue;
            }
            if (-1 != tmpObj[tk].LogicType.indexOf("Question")) {//目前只处理Question类型
                let conjuction = tmpObj[tk].Conjuction;//逻辑连词，逻辑操作 And与 Or或
                let operator = tmpObj[tk].Operator;//Selected选定；NotSelected未选定；Displayed显示；NotDisplayed未显示
                let topicNo = tmpObj[tk].QuestionID;//.replace("QID", "");//题号
                let choiceNo = getChoiceNo(tmpObj[tk].ChoiceLocator);//选项号

                if (!tmpObj[tk].hasOwnProperty('Conjuction')) { //第一个不加逻辑连词  
                    retDict[topicNo] = topicNo + "," + operDict[operator] + choiceNo;
                } else {
                    if (undefined == retDict[topicNo]) {//没有出现过该题号
                        retDict[topicNo] = topicDict[conjuction] + topicNo + "," + operDict[operator] + choiceNo;
                    } else {//出现过该题号，则拼接题项
                        let tmp = retDict[topicNo];
                        retDict[topicNo] = tmp + optionDict[conjuction] + operDict[operator] + choiceNo;
                    }
                }
            } else {
                unmanageable = "暂时无法处理";
            }
        })
        let beforeResult = window.result;
        if(undefined != beforeResult) {
            let dataArr = beforeResult.data;
            Object.keys(retDict).forEach(key => { // for (let key in retDict) {//
                let tmpVal = retDict[key];
                for(let i=0; i<dataArr.length; i++) {
                    if(key == dataArr[i].qid) {
                        retDict[key] = tmpVal.replace(key+",", dataArr[i].id+",");
                    }
                }
            })
        }
        Object.keys(retDict).forEach(key => { // for (let key in retDict) {
            result += retDict[key];
        })
    })
    if("" != unmanageable) {
        return unmanageable;
    }
    return result;
}

//获取选项个数
const getChoiceNum = function (data) {
    let num = Object.getOwnPropertyNames(data.Choices).length;
    return num;
}

const getRange = function(type, data) {
    let range = null;
    if("滑动条" == type || "矩阵滑动" == type) {
        range = {
            minvalue: parseInt(data.Configuration.CSSliderMin),
            maxvalue: parseInt(data.Configuration.CSSliderMax)
        };
    }
    return range;
}

//针对多选数量有限制的（比如最多选几个）添加到range
const getRangeIfExist = function (data) {
    let range = null;
    //处理Validation不存在的情况
    if(null == data.Validation || undefined == data.Validation) {
        return range;
    }
    let settingInfo = data.Validation.Settings;
    if(null == settingInfo || undefined == settingInfo) {
        return range;
    }
    if (settingInfo.hasOwnProperty("MinChoices")) {
        if ("ChoiceRange" == settingInfo.Type) {//区间
            range = {
                minvalue: parseInt(settingInfo.MinChoices),
                maxvalue: parseInt(settingInfo.MaxChoices)
            };
        } else if ("MinChoices" == settingInfo.Type) {//至少
            //ChoiceMinBoundary == ChoiceMaxBoundary
            range = {
                minvalue: parseInt(settingInfo.MinChoices),
                maxvalue: getChoiceNum(data)
            };
        } else if("CustomValidation" == settingInfo.Type) {//自定义
            let custLogic = settingInfo.CustomValidation.Logic;
            let oper = custLogic["0"]["0"].Operator;
            if ("EqualTo" == oper) {
                range = {
                    minvalue: parseInt(custLogic["0"]["0"].RightOperand),
                    maxvalue: parseInt(custLogic["0"]["0"].RightOperand)
                };
            } else if ("NotEqualTo" == oper) {
            } else if ("GreaterThan" == oper) {
                range = {
                    minvalue: parseInt(custLogic["0"]["0"].RightOperand) + 1,
                    maxvalue: getChoiceNum(data)
                };
            } else if ("GreaterThanOrEqual" == oper) {
                range = {
                    minvalue: parseInt(custLogic["0"]["0"].RightOperand),
                    maxvalue: getChoiceNum(data)
                };
            } else if ("LessThan" == oper) {
                range = {
                    minvalue: 1,
                    maxvalue: parseInt(custLogic["0"]["0"].RightOperand) - 1
                };
            } else if ("LessThanOrEqual" == oper) {
                range = {
                    minvalue: 1,
                    maxvalue: parseInt(custLogic["0"]["0"].RightOperand)
                };
            } else if ("Empty" == oper) {//无RightOperand
            } else if ("NotEmpty" == oper) {//无RightOperand
            } else if ("Contains" == oper) {
            } else if ("NotContains" == oper) {
            } else if ("MatchesRegex" == oper) {
            } else if ("Displayed" == oper) {//无RightOperand
            } else {// if("NotDisplayed" == oper) {//无RightOperand
            }
        } else {
            //未知
        }
    }
    return range;
}

// 获取填空题验证的ContentType类型
const getContentType = function (qst) {
    //处理Validation不存在的情况
    if(null == qst.Validation || undefined == qst.Validation) {
        return "";
    }
    let settingInfo = qst.Validation.Settings;
    if(null == settingInfo || undefined == settingInfo) {
        return "";
    }
    let ctype = qst.Validation.Settings.ContentType;
    if("ValidEmail" == ctype) {
        return "(必须邮箱)";
    } else if("ValidPhone" == ctype) {
        let ptype = qst.Validation.Settings.ValidPhoneType;
        let country = "";
        if("ValidUSPhone" == ptype) {
            country = "美国";
        } else if("ValidCAPhone" == ptype) {
            country = "加拿大";
        } else if("ValidUKPhone" == ptype) {
            country = "英国";
        } else if("ValidAUPhone" == ptype) {
            country = "澳大利亚";
        } else if("ValidNZPhone" == ptype) {
            country = "新西兰";
        } else if("ValidNLPhone" == ptype) {
            country = "荷兰";
        }
        return "(必须" + country + "电话号码)";
    } else if("ValidUSState" == ctype) {
        return "(必须美国州名或缩写)";
    } else if("ValidZip" == ctype) {
        let ztype = qst.Validation.Settings.ValidZipType;
        let country = "";
        if("ValidUSZip" == ztype) {
            country = "美国";
        } else if("ValidCAZip" == ztype) {
            country = "加拿大";
        } else if("ValidUKZip" == ztype) {
            country = "英国";
        } else if("ValidAUZip" == ztype) {
            country = "澳大利亚";
        } else if("ValidNZZip" == ztype) {
            country = "新西兰";
        } else if("ValidNLZip" == ztype) {
            country = "荷兰";
        }
        return "(必须" + country + "邮编)";
    } else if("ValidDate" == ctype) {
        return "(必须日期，格式为mm/dd/yyyy)";
    } else if("ValidNumber" == ctype) {
        return "(必须数字)";
    } else {
        return "";
    }
}

//获取问卷标题
const getSurveyTitle = function (srcData) {
    let fo = srcData.FormOptions;
    let sTitle = fo.SurveyTitle;
    if (fo.hasOwnProperty('MetaDataTranslations')) {
        let mdt = fo.MetaDataTranslations;
        if (null != mdt && mdt.hasOwnProperty('ZH-S')) {//简体中文
            sTitle = mdt["ZH-S"].SurveyTitle;
        } else if(null != mdt && mdt.hasOwnProperty('ZH-T')) {//繁体中文
            sTitle = mdt["ZH-T"].SurveyTitle;
        }
    }
    return sTitle;
}

//判断显示逻辑节点是否为空，为空返回true
const isEmpty = function(displayLogic) {
    if (null == displayLogic || undefined == displayLogic) {
        return true;
    }
    return false;
}

// 获取系统类型
const traslateType = function (type, srcType, srcQstData) {
    if ("单选" == type) {
        return "SINGLE";
    } else if ("多选" == type) {
        return "MULTIPLE";
    } else if ("下拉选项" == type) {
        return "SINGLE_SELECT";
    } else if ("排序选择" == type) {
        return "SORTED";
    } else if ("量表" == type) {
        return "SCALE";
    } else if ("矩阵单选" == type | "矩阵量表" == type) {
        return "MATRIX";
    } else if ("矩阵多选" == type) {
        return "MULTIPLE_MATRIX";
    } else if ("滑动条" == type) {
        return "SINGLE_SLIDE";
    } else if ("矩阵滑动" == type) {
        return "SLIDE";
    } else if ("比重" == type) {
        return "RATE";
    } else if ("填空" == type) {
        let conentType = srcQstData.Validation.Settings.ContentType;
        if ("TE|SL" == srcType && "ValidDate" == conentType) {//日期题
            return "DATE";
            // } else if() {//地区题
            //     return "AREA";
        } else if ("TE|FORM" == srcType) {//"多项填空"
            return "MULTIPLE_TEXT";
        } else {
            return "TEXT";
        }
    } else if ("矩阵填空" == type) {
        return "MATRIX_TEXT";
    } else if ("占位题" == type) {
        return "DESCRIPTION";
    } else {
        return type;
    }
}

// 转换为jump字典
const translate2JumpDict = function (oldJumpData) {
    let jumpDict = {};
    let len = getJsonLength(oldJumpData);
    for (let i = 0; i < len; i++) {
        jumpDict[oldJumpData[i].optionId] = oldJumpData[i].destId;
    }
    return jumpDict;
}

// 转译是否必须：0代表非必填；1代表必填
const traslateRequired = function (isReq) {
    if (isReq) { //必填
        return '1';
    }
    return '0';
}

// 判断是否为填空类题型
const isText = function (curQst) {
    if ("TEXT" == curQst.sys_type || "DATE" == curQst.sys_type || "MULTIPLE_TEXT" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {
        return true;
    }
    return false;
}

// 设置最大最小值，如果存在的话
const setMaxAndMinIfExist = function (curQst, range) {
    if("SCALE" == curQst.sys_type) { //量表不设置max和min
        return;
    }
    if (undefined == range || null == range) {
        return;
    }
    curQst.min_oper_num = range.minvalue;
    curQst.max_oper_num = range.maxvalue;
}

// 设置选项维度跳题逻辑，如果存在的话
const setJumpOnOptIfExist = function(curQst, option, jumpDict) {
    let optVal = jumpDict[option.value];
    if(curQst.is_jump && undefined != optVal) {
        option.is_jump = true; // 是否跳题
        option.jump_to = optVal; // 跳到第几题
    }
}

// 获取option的is_text字段值
const getOptionIsText = function (curQst, optName) {
    if ("SINGLE" == curQst.sys_type || "MULTIPLE" == curQst.sys_type) {
        if(optName.endsWith('|underline')) {
            return 1;//return true; //问卷星里竟然是数字1，无填空是返回false
        }
    }
    return curQst.is_text; 
}

// 转译选项
const tanslateOptions = function (optionList, curQst, srcQstData, dataIndexDict, jumpDict) {
    let optArr = new Array();
    let len = getJsonLength(optionList);
    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = optionList[i].title; // 题目的选项名称
        option.title = curQst.title + option.name; // 改成和问卷星解析一样：题目标题+选项名称
        option.value = optionList[i].optionId;//(i+1).toString();
        option.real_value = optionList[i].optionId; // 问卷提交对应的值

        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        setJumpOnOptIfExist(curQst, option, jumpDict); //设置选项维度跳题逻辑，如果存在的话

        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = getOptionIsText(curQst, option.name); // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵or多填
        if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {//多选每个选项都要有索引
            option.data_index = lastDataIndex + i; // 数据库索引
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        } else {
            option.data_index = lastDataIndex; // 数据库索引
        }
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    } else if("DESCRIPTION" == curQst.sys_type) {
        //描述类占位题不生成dataIndexDict值
    } else {
        dataIndexDict["curQstDataIndex"].push(lastDataIndex);
        dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    }
    return optArr;
}

// 构建填空option
const buildTextOption = function (curQst, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = ""; // 题目的选项名称
    option.value = "1";
    option.real_value = ""; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取矩阵多选的子节点选项
const getChildOptionOnly4MultiMatrix = function(len, curQst, oldData, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let optArr = new Array();
    let qst = oldData.srcQstData;
    let la = qst.SurveyLanguage;
    let la_zh = "";
    if (qst.Language.hasOwnProperty("ZH-S")) {//简体中文
        la_zh = "ZH-S";
    } else if(qst.Language.hasOwnProperty("ZH-T")) {//繁体中文
        la_zh = "ZH-T";
    }
    let answers = getAnswers(qst, la, la_zh);
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + answers[i+1].Display; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = answers[i+1].Display; // 题目的选项名称
        option.value = (i+1).toString();
        option.real_value = (i+1).toString(); // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = lastDataIndex + i; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
    }
    dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    return optArr;
}

// 获取子节点选项（只针对矩阵or多填）
const getChildOption = function (maxNum, curQst, oldData) {
    let optArr = new Array();
    let qst = oldData.srcQstData;
    let la = qst.SurveyLanguage;
    let la_zh = "";
    if (qst.Language.hasOwnProperty("ZH-S")) {//简体中文
        la_zh = "ZH-S";
    } else if(qst.Language.hasOwnProperty("ZH-T")) {//繁体中文
        la_zh = "ZH-T";
    }
    if ("MULTIPLE_TEXT" == curQst.sys_type || "SLIDE" == curQst.sys_type || "SINGLE_SLIDE" == curQst.sys_type) { // 多项填空or矩阵滑动条或滑动条
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title; // 父题目
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = curQst.name; // 题目的选项名称
        option.value = (curQst.value).toString();
        option.real_value = (curQst.real_value).toString(); // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        return optArr;
    }
    if (undefined == maxNum || null == maxNum) {
        return optArr;
    }
    let answers = null;
    if("SBS" == qst.QuestionType) {
        answers = getAddtQstAnswers(qst, la);
    } else if("Matrix" == qst.QuestionType) {
        answers = getAnswers(qst, la, la_zh);
    }
    let answerOrder = qst.AnswerOrder;//矩阵类才有
    for (let i = 0; i < maxNum; i++) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + answers[answerOrder[i]].Display; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = answers[answerOrder[i]].Display; // 题目的选项名称
        option.value = (i+1).toString();
        option.real_value = (i+1).toString(); // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    return optArr;
}

// 获取choices内元素key的数组列表
const getChoiceList = function (choices) {
    let choiceList = new Array();
    Object.keys(choices).forEach(key => {
        choiceList.push(key);
    })
    return choiceList;
}

// 获取choices
const getChoices = function (qst, la, la_zh) {
    let choices = qst.Language[la].Choices;
    if(undefined == choices || null == choices) {
        choices = qst.Language[qst.SurveyLanguage].Choices;
    }
    if ("" != la_zh) {
        let choices_zh = "";
        choices_zh = qst.Language[la_zh].Choices;
        if(undefined == choices || null == choices) {
            choices_zh = qst.Language[qst.SurveyLanguage].Choices;
        }
        // 合并两个choices
        for (let key in choices_zh) {
            if (choices.hasOwnProperty(key)) {
                choices[key] = choices_zh[key];
            }
        }
    }
    return choices;
}

// 获取answers
const getAnswers = function (qst, la, la_zh) {
    let answers = qst.Language[la].Answers;
    if(undefined == answers || null == answers) {
        answers = qst.Language[qst.SurveyLanguage].Answers;
    }
    if ("" != la_zh) {
        let answers_zh = "";
        answers_zh = qst.Language[la_zh].Answers;
        if(undefined == answers || null == answers) {
            answers_zh = qst.Language[qst.SurveyLanguage].Answers;
        }
        // 合并两个answers
        for (let key in answers_zh) {
            if (answers.hasOwnProperty(key)) {
                answers[key] = answers_zh[key];
            }
        }
    }
    return answers;
}

// 获取additionalQuestions的answers
const getAddtQstAnswers = function (qst, la) {
    let addtQstAnswers = qst.AdditionalQuestions['1'].Language[la].Answers;
    if(undefined == addtQstAnswers || null == addtQstAnswers) {
        addtQstAnswers = qst.AdditionalQuestions['1'].Language[qst.SurveyLanguage].Answers;
    }
    return addtQstAnswers;
}

// 获取子选项（只针对矩阵or多填）
const getChildren = function (oldData, curQst, dataIndexDict) {
    let optionList = oldData.inner;
    let range = oldData.range;
    let childArr = new Array();

    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let len = 0;
    let qst = oldData.srcQstData;
    let la = qst.SurveyLanguage;
    let la_zh = "";
    if (qst.Language.hasOwnProperty("ZH-S")) {//简体中文
        la_zh = "ZH-S";
    } else if(qst.Language.hasOwnProperty("ZH-T")) {//繁体中文
        la_zh = "ZH-T";
    }
    let choices = getChoices(qst, la, la_zh);
    let answers = getAnswers(qst, la, la_zh);
    if ("MATRIX" == curQst.sys_type || "MULTIPLE_MATRIX" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        len = getJsonLength(choices);
        let choiceList = getChoiceList(choices);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + choices[choiceList[i]].Display; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = choices[choiceList[i]].Display; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = ""; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            if("MULTIPLE_MATRIX" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {//矩阵多选or矩阵填空
                curChild.options = getChildOptionOnly4MultiMatrix(getJsonLength(answers), curChild, oldData, dataIndexDict); // 选项
                curChild.data_index = dataIndexDict["lastDataIndex"] - 1; // 数据库索引
                // dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"]);
                // dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + 1;
            } else {
                curChild.data_index = dataIndexDict["lastDataIndex"] + i; // 数据库索引
                dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"] + i);
                if("SBSMatrix" == qst.Selector) {
                    let answers = getAddtQstAnswers(qst, la);
                    curChild.options = getChildOption(getJsonLength(answers), curChild, oldData); // 选项
                } else {
                    curChild.options = getChildOption(getJsonLength(answers), curChild, oldData); // 选项
                }
            }
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
        }
        if("MULTIPLE_MATRIX" != curQst.sys_type && "MATRIX_TEXT" != curQst.sys_type) {//不是矩阵多选和矩阵填空
            dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + len;
        }
    } else if("MULTIPLE_TEXT" == curQst.sys_type) {//多项填空
        len = getJsonLength(oldData.srcQstData.Choices);
        let choiceList = getChoiceList(choices);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + choices[choiceList[i]].Display; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = choices[choiceList[i]].Display; // 题目的选项名称
            curChild.value = i+1;
            curChild.real_value = ""; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption(getJsonLength(oldData.srcQstData.Choices), curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    } else {
        len = getJsonLength(optionList);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + optionList[i].title == undefined? "": optionList[i].title; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = optionList[i].title.split("_")[0]; // 题目的选项名称
            curChild.value = i+1;
            curChild.real_value = optionList[i].optionId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption((range == undefined || range == null) ? null : range.maxvalue, curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    }
    return childArr;
}

// 获取data_index数据中的多选选项
const getDataIdxCheckboxOption = function (curQst, dataIndexDict, idx) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = curQst.name; // 题目的选项名称
    option.value = idx+1;
    option.real_value = curQst.value; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取选项option的值列表
const getOptionsValueList = function (options) {
    let valueList = new Array();
    for (let i = 0; i < options.length; i++) {
        valueList.push(options[i].value);
    }
    return valueList;
}

// 获取选项option的范围值列表
const getOptionsRangeValueList = function (curData) {
    let valueList = new Array();
    let minVal = curData.min_oper_num;
    let maxVal = curData.max_oper_num;
    for (let i = minVal; i <= maxVal; i++) {
        valueList.push(i);
    }
    return valueList;
}

// 增加valid_values字段
const addValidValues = function (dataIndexArr) {
    let len = getJsonLength(dataIndexArr);
    let sortedQstList = new Array();// 排序题列表，由于其值分散需要收集到一起
    let sortedQstValueList = [-3, -2]; // 排序题值列表
    // 根据每道题的类型添加valid_values字段
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("SINGLE" == curData.sys_type) {// 单选题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE" == curData.sys_type) {// 多选题
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SELECT" == curData.sys_type) {// 下拉选择
            curData.valid_values = [-3, -2].concat(getOptionsValueList(curData.options));
        } else if ("SORTED" == curData.sys_type) {// 排序题
            sortedQstList.push(curData);
            sortedQstValueList = sortedQstValueList.concat(getOptionsValueList(curData.options));
        } else if ("SCALE" == curData.sys_type) {// 量表题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MATRIX" == curData.sys_type) {// 矩阵单选
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE_MATRIX" == curData.sys_type) {// 矩阵多选
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单项滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("SLIDE" == curData.sys_type) {// 矩阵滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("RATE" == curData.sys_type) {// 比重题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("DATE" == curData.sys_type) {// 日期题
            curData.valid_values = null;
        } else if ("AREA" == curData.sys_type) {// 地区题
            curData.valid_values = null;
        } else if ("TEXT" == curData.sys_type) {// 填空题
            curData.valid_values = null;
        } else if ("MULTIPLE_TEXT" == curData.sys_type) {// 多项填空
            curData.valid_values = null;
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空
            curData.valid_values = null;
        } else {// DESCRIPTION描述类占位题
            curData.valid_values = null;
        }
    }
    // 处理排序题的valid_values字段
    // let valid_values = [-3, -2].concat(sortedQstValueList);
    for (let i = 0; i < sortedQstList.length; i++) {
        let curData = sortedQstList[i];
        curData.valid_values = sortedQstValueList;
    }
}

// 获取data_index数据
const getDataIndexArr = function (result) {
    let dataIndexArr = new Array(); // 数据库对应的数据

    let counter = 0;
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        //console.log(key);
        // if ("多选" == dataArr[i].type) {
        //     let optionList = dataArr[i].inner;
        //     let len = getJsonLength(optionList);
        //     for (let j = 0; j < len; j++) {
        //         let curData = dataArr[i];
        //         let tmp = new Object();
        //         tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        //         tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        //         tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        //         tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        //         tmp.sys_type = traslateType(curData.type, curData.srcType, curData.srcQstData); // 内部平台题目类型
        //         tmp.name = tmp.title; // 题目名称，同title
        //         tmp.value = ""; // 值 - 题目维度下不需要填
        //         tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        //         tmp.jump_to = null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        //         tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        //         tmp.is_text = isText(tmp); // 是否填空题 bool
        //         tmp.relation = curData.relation;
        //         tmp.min_oper_num = 0; // 最小值
        //         tmp.max_oper_num = 0; // 最大值
        //         setMaxAndMinIfExist(tmp, curData.range);
        //         tmp.rate = 0; // 权重 - 题目维度下不需要填
        //         tmp.text = ""; // 填空内容 - 题目维度下不需要填
        //         tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        //         tmp.options = [getDataIdxCheckboxOption(tmp, dataIndexDict, j)];
        //         tmp.children = [];
        //         tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        //         dataIndexDict["curQstDataIndex"] = [];

        //         dataIndexArr.push(tmp);
        //     }
        // } else {
        let jumpDict = {};
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType, curData.srcQstData); // 内部平台题目类型
        tmp.name = curData.title; // 题目名称，给制单人看的
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type || "SLIDE" == tmp.sys_type || "SINGLE_SLIDE" == tmp.sys_type) { // 矩阵or多填题or滑动条
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else {
            tmp.options = tanslateOptions(curData.inner, tmp, curData.srcQstData, dataIndexDict, jumpDict); // 选项
        }
        if("DESCRIPTION" != tmp.sys_type) {//描述类占位题不生成dataIndexDict值
            tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        }
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        if("DESCRIPTION" == tmp.sys_type) {//暂时不处理不显示描述类题型
            continue;
        }
        dataIndexArr.push(tmp);
        // }
    }
    let newDataIndexArr = convertDataIndexArr(dataIndexArr); // 转换data_index数组为wjx格式
    addValidValues(newDataIndexArr); // 增加valid_values字段
    return newDataIndexArr;//dataIndexArr;
}

// 转换data_index数组为wjx格式
const convertDataIndexArr = function (dataIndexArr) {
    let newDataIndexArr = new Array();
    let len = getJsonLength(dataIndexArr);
    counter = 0;
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("MULTIPLE_MATRIX" == curData.sys_type ) {// 矩阵多选：拆children中的options，但option值取原来整体options
            for (let j = 0; j < curData.children.length; j++) {//遍历children
                let child = curData.children[j];
                let options = child.options;
                let optStr = JSON.stringify(options);
                for (let k = 0; k < options.length; k++) {
                    let newTmp = options[k];
                    newTmp.index = counter++;
                    newTmp.options = JSON.parse(optStr);
                    newDataIndexArr.push(newTmp);
                }
            }
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空：拆children中的options
            curData.children.forEach(child => {
                child.options.forEach(option => {                        
                    let newTmp = option;
                    newTmp.index = counter++;
                    newTmp.options = [JSON.parse(JSON.stringify(option))];
                    newDataIndexArr.push(newTmp);
                });                    
            });
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单选滑动条：拆options，但title和name取原来整体title和name
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.title = curData.title;
                newTmp.name = curData.name;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MATRIX" == curData.sys_type || "MULTIPLE_TEXT" == curData.sys_type || "SLIDE" == curData.sys_type ) { // 矩阵or多填题：拆children
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MULTIPLE" == curData.sys_type || "SORTED" == curData.sys_type || "RATE" == curData.sys_type ) { // 多选，排序和比重题：拆options
            curData.options.forEach(option => {
                let newTmp = option;
                newTmp.index = counter++;
                newTmp.options = [JSON.parse(JSON.stringify(option))];
                newDataIndexArr.push(newTmp);
            });
        } else {
            let newTmp = curData;
            newTmp.index = counter++;
            newDataIndexArr.push(newTmp);
        }
    }
    return newDataIndexArr;
}

// 将指定json数据中的value的值替换成同层real_value的值，并删除real_value
const replaceValueWithRealValue = function (jsonData) {
    if (jsonData == null) {
        return null;
    }
    // 递归遍历 JSON 数据
    const traverse = function (obj) {
        if (typeof obj !== 'object' || obj === null) {
            return;
        }
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (key === 'value' && obj.hasOwnProperty('real_value')) {
                    obj[key] = obj['real_value'];
                    delete obj['real_value'];
                } else {
                    traverse(obj[key]);
                }
            }
        }
    };
    traverse(jsonData);
    return jsonData;
};

// 转换为新的结果
const translate2newResult = function (result, resultNew) {
    let listDataArr = new Array(); // 返回的题目内容列表
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        let jumpDict = {};
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType, curData.srcQstData); // 内部平台题目类型
        tmp.name = curData.title; // 题目名称，给制单人看的
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type || "SLIDE" == tmp.sys_type || "SINGLE_SLIDE" == tmp.sys_type) { // 矩阵or多填题or滑动条
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else {
            tmp.options = tanslateOptions(curData.inner, tmp, curData.srcQstData, dataIndexDict, jumpDict); // 选项
        }
        if("DESCRIPTION" != tmp.sys_type) {//描述类占位题不生成dataIndexDict值
            tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        }
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        if("DESCRIPTION" == tmp.sys_type) {//暂时不处理不显示描述类题型
            continue;
        }
        listDataArr.push(tmp);
    }
    resultNew.list = replaceValueWithRealValue(listDataArr);//相关分析需要删除real_value才能运行成功
    resultNew.data_index = getDataIndexArr(result);
    resultNew.total_data_index = dataIndexDict["lastDataIndex"];
}


const fs = require('fs');
// const srcData = QSettings.pt;
let window = { counter: 0, result: {data: []} };// 用于测试
//加载题目主体函数定义
const getDataArr = function (sdata_file) {
    // console.log("==================================== enter js ====================================");
    let sdata = "";
    try {
        const data = fs.readFileSync(sdata_file);
        // console.log(data.toString());
        sdata = data.toString();
    } catch (err) {
        console.error(err);
    }
    let srcData = str2json(sdata);
    let resultNew = { list: [], data_index: [], total_data_index: 0 };//list代表问卷的所有题目；data_index代表数据库对应的数据；

    var result = { title: '', error: '', data: [] };//error内容为加载失败消息：如问卷暂停、需微信登录等
    var dataArray = new Array(); // 返回的题目内容列表
    if (window.counter == null) {
        window.counter = 0;
    }
    
    // var pageLen = getJsonLength(srcData.QuestionDefinitions.pages);
    let questions = srcData.QuestionDefinitions;
    let errIds = '';
    Object.keys(questions).forEach(key => { // for (let key in questions) {//
        // console.log(questions[key]);
        var tmp = new Object();
        tmp.id = ++(window.counter); // 全局题号 ，从1开始递增。 
        tmp.qid = questions[key].QuestionID; // 题目id（提交使用的ID）
        tmp.type = getType(questions[key]);  // 见typeName 定义 返回字符串
        tmp.srcType = questions[key].QuestionType + "|" + questions[key].Selector; //题目原始类型，格式：主类型|子类型
        tmp.range = getRange(tmp.type, questions[key]);
        let dl = questions[key].DisplayLogic;
        tmp.relation = getRelation(isEmpty(dl) ? questions[key].InPageDisplayLogic : dl);//赋值关联项;见关联字符串定义(显示逻辑)
        tmp.hasJump = false;
        tmp.jumpData = null;
        tmp.inner = getOptions(questions[key], tmp); // 选项数据。 见选项数据定义
        tmp.isRequired = getRequired(questions[key]); // 是否必选。
        tmp.title = getTitle(questions[key]); // 题目标题，需要避免使用特殊字符“_”

        if("填空" == tmp.type) {
            tmp.title += getContentType(questions[key]);
        }
        if ("多选" == tmp.type) {
            tmp.range = getRangeIfExist(questions[key]);
        }
        if (-1 != tmp.type.indexOf("矩阵") && questions[key].hasOwnProperty("AdditionalQuestions")) {
            errIds += tmp.id + ',';
        }
        if (0 == tmp.inner.length && ('单选' == tmp.type || '多选' == tmp.type || '排序选择' == tmp.type)) {
            tmp.type = '占位题';
        }

        tmp.srcQstData = questions[key];
        dataArray.push(tmp); 
    })

    if('' != errIds) {
        result.error = '矩阵打分题型不支持(题号' + errIds.substring(0, errIds.length-1) + ')';
    }
    result.title = getSurveyTitle(srcData);
    result.data = dataArray;
    if (dataArray.length == 0) {
        result.error = srcData.ErrorCode;
    }
    if (srcData.IsPageMessage && srcData.Messages) {
        result.error += srcData.Messages.PageMessage;
    }

    translate2newResult(result, resultNew);
    return resultNew; // return result; // 
};

// getDataArr(param1);//测试结果
console.log(JSON.stringify(getDataArr(param1)));//测试输出结果
